﻿using System;

namespace Libs.Egucha
{
    static class Collision
    {
        /// <summary>
        /// 矩形同士の当たり判定を行う
        /// </summary>
        public static bool GetIsHitRectAndRect(Rect par1Rect, Rect par2Rect)
        {
            return (par1Rect.leftTopPos.x < par2Rect.rightBottomPos.x) &&
                   (par2Rect.leftTopPos.x < par1Rect.rightBottomPos.x) &&
                   (par1Rect.leftTopPos.y < par2Rect.rightBottomPos.y) &&
                   (par2Rect.leftTopPos.y < par1Rect.rightBottomPos.y);
        }

        /// <summary>
        /// 線分同士の当たり判定を行う
        /// </summary>
        public static bool GetIsHitLineAndLine(Line par1Line, Line par2Line)
        {
            Vector av = par1Line.endPos - par1Line.startPos;
            Vector bv = par2Line.startPos - par1Line.startPos;
            Vector cv = par2Line.endPos - par1Line.startPos;
            Vector dv = par2Line.endPos - par2Line.startPos;
            Vector ev = par1Line.startPos - par2Line.startPos;
            Vector fv = par1Line.endPos - par2Line.startPos;

            double a = Helper.GetCrossProduct(av, bv);
            double b = Helper.GetCrossProduct(av, cv);
            double c = Helper.GetCrossProduct(dv, ev);
            double d = Helper.GetCrossProduct(dv, fv);

            return (((a * b) < 0.0d) && ((c * d) < 0.0d));
        }

        /// <summary>
        /// 矩形と点の当たり判定を行う
        /// </summary>
        public static bool GetIsHitRectAndPoint(Rect par1Rect, PointD par2Point)
        {
            return (par1Rect.leftTopPos.x < par2Point.x) &&
                   (par2Point.x < par1Rect.rightBottomPos.x) &&
                   (par1Rect.leftTopPos.y < par2Point.y) &&
                   (par2Point.y < par1Rect.rightBottomPos.y);
        }

        /// <summary>
        /// 矩形と線分の当たり判定を行う
        /// </summary>
        public static bool GetIsHitLineAndRect(Line par1Line, Rect par2Rect)
        {
            if (GetIsHitRectAndPoint(par2Rect, par1Line.startPos) ||
                GetIsHitRectAndPoint(par2Rect, par1Line.endPos))
            {
                return true;
            }

            return GetIsHitLineAndLine(par1Line, new Line(par2Rect.leftTopPos, par2Rect.rightBottomPos)) ||
                   GetIsHitLineAndLine(par1Line, new Line(new PointD(par2Rect.rightBottomPos.x, par2Rect.leftTopPos.y),
                                                          new PointD(par2Rect.leftTopPos.x, par2Rect.rightBottomPos.y)));
        }

        /// <summary>
        /// 円同士の当たり判定を行う
        /// </summary>
        public static bool GetIsHitCircleAndCircle(Circle par1Circle, Circle par2Circle)
        {
            return (Math.Pow(par1Circle.pos.x - par2Circle.pos.x, 2) +
                        Math.Pow(par1Circle.pos.y - par2Circle.pos.y, 2)) <
                   (Math.Pow(par1Circle.radius + par2Circle.radius, 2));
        }
    }
}
